#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import sys
import time

from common.common_models import LogDetail

from common.common import exter_attack
from common.const import SysData, ReportDBLabel, DBLogLevel
from exchange import log
from exchange.backup.backup_base.base_exchange_backup_pre_job import ExchangeBackupPrePare
from exchange.commons.common import get_key_value, get_mounted_databases_by_server
from exchange.commons.const import ExchangeJobInfo, BodyErr
from exchange.commons.exchange_exception import ExchangeErrCodeException
from exchange.commons.exchange_function_tool import log_start_end, out_result_with_job_info, \
    progress_notify_with_job_info


def get_backup_database_size(database_flag, m_password, m_username, nodes):
    for node in nodes:
        server_name = node["name"]
        db_names = get_mounted_databases_by_server(m_username, m_password, server_name)
        database_flag = database_flag + len(db_names)
    return database_flag


class DagBackupPreJob(ExchangeBackupPrePare):
    def __init__(self, pid):
        super().__init__(pid)
        self._pid = pid

    @log_start_end()
    @out_result_with_job_info()
    @progress_notify_with_job_info()
    def do_prepare_task(self, job_info: ExchangeJobInfo):
        self.clean_last_copy_data()
        flags, m_username = get_key_value(f'job_protectEnv_auth_authKey_{job_info.pid}')
        flags, m_password = get_key_value(f'job_protectEnv_auth_authPwd_{job_info.pid}')
        nodes = self._param.get("job").get("protectEnv").get("nodes")
        database_flag = 0
        retry_count = 0
        while retry_count < 3:
            # 如果可备份数据库信息为0，有可能是服务重启，重试3次
            database_flag = get_backup_database_size(database_flag, m_password, m_username, nodes)
            if database_flag < 1:
                retry_count += 1
                if retry_count == 3:
                    log.error(f"this exchange group have no database can backup, {job_info.log_format()}.")
                    raise ExchangeErrCodeException(log_detail=LogDetail(logInfo=ReportDBLabel.PRE_REQUISIT_FAILED,
                                                                        logDetail=BodyErr.ALL_DATABASE_NOT_EXIST.value,
                                                                        logTimestamp=int(time.time()),
                                                                        logLevel=DBLogLevel.ERROR))
                else:
                    # 阻塞30秒后重试
                    time.sleep(30)
            else:
                break
        return True


@exter_attack
def do_exec(pid):
    try:
        job = DagBackupPreJob(pid)
        job.do_prepare_task(job.get_job_info())
    except ExchangeErrCodeException as err_str:
        log.error(f"Post backup failed, err: {err_str}, pid:{pid}")
        return False
    return True

if __name__ == '__main__':
    for line in sys.stdin:
        SysData.SYS_STDIN = line
        break

    if len(sys.argv) < 1:
        log.error("Param is wrong.")
        sys.exit(1)
    pid_args2 = sys.argv[1]
    try:
        do_exec(pid_args2)
    except Exception as err:
        log.error(f"Err: {err}, pid: {pid_args2}")
        sys.exit(0)

    sys.exit(0)